package com.only.webServer;

import com.only.webServer.request.HttpMethod;
import com.only.webServer.request.HttpRequest;
import com.only.webServer.response.HttpResponse;
import com.only.webServer.servlet.Servlet;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 调度Servlet
 */
@Slf4j
public class DispatcherServlet {
    private static ConcurrentHashMap<String, Servlet> servletPool = new ConcurrentHashMap<String, Servlet>();

    static {
        log.info("初始化 servletPool ...");
        // 初始化 servletPool
        // 全类名和类
        Map<String, Object> map = new HashMap<>();
        try {
            InputStream in = Main.class.getClassLoader().getResourceAsStream("web.xml");
            Document parse = Jsoup.parse(in, "UTF-8", "/");
            in.close();
            Elements allClass = parse.getElementsByTag("class");
            for (Element classElement : allClass) {
                map.put(classElement.text(), Class.forName(classElement.text()).newInstance());
            }
            Elements servlet = parse.getElementsByTag("servlet");
            for (Element element : servlet) {
                Elements path = element.getElementsByTag("path-mapper");
                Elements aClass = element.getElementsByTag("class");
                servletPool.put(path.text(), (Servlet) map.get(aClass.text()));
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("cannot be resolved web.xml");
            System.exit(-1);
        }
        log.info("servletPool Initialize successfully");
    }

    /**
     * 分发servlet
     * 如果重定向需要改变httpRequest的PathMapping来完成
     * @param httpRequest
     * @param httpResponse
     */
    public static void dispense(HttpRequest httpRequest, HttpResponse httpResponse) {
        // 路由没找到可能访问的是静态文件所以调用静态的servlet
        Servlet servlet = servletPool.getOrDefault(httpRequest.getPathMapping(), servletPool.get("/public"));
        if (HttpMethod.GET == httpRequest.getMethod()) {
            servlet.doGet(httpRequest, httpResponse);
        } else if (HttpMethod.POST == httpRequest.getMethod()) {
            servlet.doPost(httpRequest, httpResponse);
        }
    }
}
